// 动态导入jsQR以解决ES模块兼容性问题
let jsQR: any = null

// 初始化jsQR
const initJsQR = async () => {
  if (!jsQR) {
    try {
      const jsQRModule = await import('jsqr')
      jsQR = jsQRModule.default || jsQRModule
      
      // 验证jsQR函数是否可用
      if (typeof jsQR !== 'function') {
        console.error('jsQR不是一个函数:', jsQR)
        throw new Error('jsQR库导入异常')
      }
    } catch (error) {
      console.error('jsQR动态导入失败:', error)
      throw new Error('无法加载jsQR库: ' + (error instanceof Error ? error.message : '未知错误'))
    }
  }
  return jsQR
}

export interface DecodeResult {
  id: string
  content: string
  type: QrCodeType
  timestamp: number
  source: 'upload' | 'camera'
  originalImage?: string
}

export enum QrCodeType {
  URL = 'url',
  TEXT = 'text',
  WIFI = 'wifi',
  VCARD = 'vcard',
  EMAIL = 'email',
  PHONE = 'phone',
  SMS = 'sms',
  UNKNOWN = 'unknown'
}

/**
 * 从图片文件解码二维码
 * @param file 图片文件
 * @returns Promise<DecodeResult>
 */
export const decodeFromFile = (file: File): Promise<DecodeResult> => {
  return new Promise(async (resolve, reject) => {
    try {
      
      // 确保jsQR已加载
      await initJsQR()
      
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      const img = new Image()
      
      if (!ctx) {
        console.error('无法创建Canvas上下文')
        reject(new Error('无法创建Canvas上下文'))
        return
      }
      
      img.onload = () => {
        try {
          
          // 检查图片尺寸是否合理
          if (img.width === 0 || img.height === 0) {
            console.error('图片尺寸异常:', img.width, 'x', img.height)
            reject(new Error('图片尺寸异常，无法处理'))
            return
          }
          
          canvas.width = img.width
          canvas.height = img.height
          ctx.drawImage(img, 0, 0)

          
          const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
          
          const code = jsQR(imageData.data, imageData.width, imageData.height, {
            inversionAttempts: 'dontInvert'
          })

          
          if (code) {
            const result: DecodeResult = {
              id: generateId(),
              content: code.data,
              type: detectQrCodeType(code.data),
              timestamp: Date.now(),
              source: 'upload'
            }
            resolve(result)
          } else {
            // 尝试反色处理
            const invertedImageData = invertImageData(imageData)
            const invertedCode = jsQR(invertedImageData.data, invertedImageData.width, invertedImageData.height)
            
            if (invertedCode) {
              const result: DecodeResult = {
                id: generateId(),
                content: invertedCode.data,
                type: detectQrCodeType(invertedCode.data),
                timestamp: Date.now(),
                source: 'upload'
              }
              resolve(result)
            } else {
              console.error('所有解码尝试都失败了')
              reject(new Error('无法识别二维码，请确保图片清晰且包含有效的二维码'))
            }
          }
        } catch (error) {
          console.error('图片处理过程中发生错误:', error)
          reject(new Error('图片处理失败: ' + (error instanceof Error ? error.message : '未知错误')))
        }
      }
      
      img.onerror = (event) => {
        console.error('图片加载失败事件:', event)
        reject(new Error('图片加载失败，请检查图片格式是否正确'))
      }
      
      // 创建图片URL
      try {
        const imageUrl = URL.createObjectURL(file)
        img.src = imageUrl
        
        // 清理URL对象
        img.onload = (originalOnload => {
          return function(this: HTMLImageElement, ev: Event) {
            URL.revokeObjectURL(this.src)
            return originalOnload.call(this, ev)
          }
        })(img.onload!)
        
      } catch (error) {
        console.error('创建图片URL失败:', error)
        reject(new Error('无法读取图片文件: ' + (error instanceof Error ? error.message : '未知错误')))
      }
    } catch (error) {
      console.error('解码初始化失败:', error)
      reject(new Error('初始化失败: ' + (error instanceof Error ? error.message : '未知错误')))
    }
  })
}

/**
 * 从视频帧解码二维码
 * @param video 视频元素
 * @returns DecodeResult | null
 */
export const decodeFromVideo = (video: HTMLVideoElement): DecodeResult | null => {
  if (!video || video.readyState !== video.HAVE_ENOUGH_DATA) {
    return null
  }
  
  const canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')
  
  if (!ctx) {
    return null
  }
  
  canvas.width = video.videoWidth
  canvas.height = video.videoHeight
  ctx.drawImage(video, 0, 0)
  
  try {
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
    const code = jsQR(imageData.data, imageData.width, imageData.height, {
      inversionAttempts: 'dontInvert'
    })
    
    if (code) {
      return {
        id: generateId(),
        content: code.data,
        type: detectQrCodeType(code.data),
        timestamp: Date.now(),
        source: 'camera'
      }
    }
    
    // 尝试反色处理
    const invertedImageData = invertImageData(imageData)
    const invertedCode = jsQR(invertedImageData.data, invertedImageData.width, invertedImageData.height)
    
    if (invertedCode) {
      return {
        id: generateId(),
        content: invertedCode.data,
        type: detectQrCodeType(invertedCode.data),
        timestamp: Date.now(),
        source: 'camera'
      }
    }
  } catch (error) {
    console.error('视频帧解码失败:', error)
  }
  
  return null
}

/**
 * 检测二维码类型
 * @param content 二维码内容
 * @returns QrCodeType
 */
export const detectQrCodeType = (content: string): QrCodeType => {
  if (!content) {
    return QrCodeType.UNKNOWN
  }
  
  // URL检测 - 支持http、https、ftp等协议
  if (/^(https?|ftp):\/\//i.test(content)) {
    return QrCodeType.URL
  }
  
  // WiFi检测
  if (/^WIFI:/i.test(content)) {
    return QrCodeType.WIFI
  }
  
  // vCard检测
  if (/^BEGIN:VCARD/i.test(content)) {
    return QrCodeType.VCARD
  }
  
  // 邮箱检测
  if (/^mailto:/i.test(content) || /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(content)) {
    return QrCodeType.EMAIL
  }
  
  // 电话检测
  if (/^tel:/i.test(content) || /^[+]?[\d\s\-\(\)]{7,}$/.test(content.trim())) {
    return QrCodeType.PHONE
  }
  
  // 短信检测
  if (/^sms:/i.test(content) || /^smsto:/i.test(content)) {
    return QrCodeType.SMS
  }
  
  // 默认为文本
  return QrCodeType.TEXT
}

/**
 * 反转图像数据（用于处理反色二维码）
 * @param imageData 原始图像数据
 * @returns 反转后的图像数据
 */
const invertImageData = (imageData: ImageData): ImageData => {
  const data = new Uint8ClampedArray(imageData.data)
  
  for (let i = 0; i < data.length; i += 4) {
    // 反转RGB值，保持Alpha不变
    data[i] = 255 - data[i]         // Red
    data[i + 1] = 255 - data[i + 1] // Green
    data[i + 2] = 255 - data[i + 2] // Blue
    // data[i + 3] = data[i + 3]    // Alpha保持不变
  }
  
  return new ImageData(data, imageData.width, imageData.height)
}

/**
 * 生成唯一ID
 * @returns 唯一标识符
 */
const generateId = (): string => {
  return Date.now().toString(36) + Math.random().toString(36).substr(2, 9)
}

/**
 * 预处理图像以提高识别率
 * @param imageData 原始图像数据
 * @returns 处理后的图像数据
 */
export const preprocessImage = (imageData: ImageData): ImageData => {
  const data = new Uint8ClampedArray(imageData.data)
  
  // 转换为灰度图像
  for (let i = 0; i < data.length; i += 4) {
    const gray = Math.round(0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2])
    data[i] = gray     // Red
    data[i + 1] = gray // Green
    data[i + 2] = gray // Blue
    // Alpha保持不变
  }
  
  // 应用阈值处理（二值化）
  const threshold = 128
  for (let i = 0; i < data.length; i += 4) {
    const value = data[i] > threshold ? 255 : 0
    data[i] = value     // Red
    data[i + 1] = value // Green
    data[i + 2] = value // Blue
  }
  
  return new ImageData(data, imageData.width, imageData.height)
}

/**
 * 验证二维码内容格式
 * @param content 二维码内容
 * @param type 二维码类型
 * @returns 验证结果
 */
export const validateQrCodeContent = (content: string, type: QrCodeType): { valid: boolean; message?: string } => {
  switch (type) {
    case QrCodeType.URL:
      try {
        new URL(content)
        return { valid: true }
      } catch {
        return { valid: false, message: '无效的URL格式' }
      }
    
    case QrCodeType.EMAIL:
      const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
      if (content.startsWith('mailto:')) {
        const email = content.substring(7)
        return emailRegex.test(email) ? { valid: true } : { valid: false, message: '无效的邮箱格式' }
      }
      return emailRegex.test(content) ? { valid: true } : { valid: false, message: '无效的邮箱格式' }
    
    case QrCodeType.PHONE:
      const phoneRegex = /^[+]?[\d\s\-\(\)]{7,}$/
      if (content.startsWith('tel:')) {
        const phone = content.substring(4)
        return phoneRegex.test(phone) ? { valid: true } : { valid: false, message: '无效的电话号码格式' }
      }
      return phoneRegex.test(content) ? { valid: true } : { valid: false, message: '无效的电话号码格式' }
    
    case QrCodeType.WIFI:
      return content.startsWith('WIFI:') ? { valid: true } : { valid: false, message: '无效的WiFi格式' }
    
    case QrCodeType.VCARD:
      return content.includes('BEGIN:VCARD') && content.includes('END:VCARD') 
        ? { valid: true } 
        : { valid: false, message: '无效的vCard格式' }
    
    default:
      return { valid: true }
  }
}

/**
 * 格式化二维码内容用于显示
 * @param content 原始内容
 * @param type 二维码类型
 * @returns 格式化后的内容
 */
export const formatQrCodeContent = (content: string, type: QrCodeType): string => {
  switch (type) {
    case QrCodeType.WIFI:
      // 解析WiFi信息并格式化显示
      const wifiMatch = content.match(/WIFI:T:([^;]*);S:([^;]*);P:([^;]*);H:([^;]*);?/)
      if (wifiMatch) {
        return `网络名称: ${wifiMatch[2]}\n加密方式: ${wifiMatch[1] || '无'}\n密码: ${wifiMatch[3] || '无密码'}\n隐藏网络: ${wifiMatch[4] === 'true' ? '是' : '否'}`
      }
      break
    
    case QrCodeType.VCARD:
      // 解析vCard信息并格式化显示
      const lines = content.split('\n')
      const vCardInfo: string[] = []
      
      lines.forEach(line => {
        if (line.startsWith('FN:')) {
          vCardInfo.push(`姓名: ${line.substring(3)}`)
        } else if (line.startsWith('ORG:')) {
          vCardInfo.push(`组织: ${line.substring(4)}`)
        } else if (line.startsWith('TEL:')) {
          vCardInfo.push(`电话: ${line.substring(4)}`)
        } else if (line.startsWith('EMAIL:')) {
          vCardInfo.push(`邮箱: ${line.substring(6)}`)
        }
      })
      
      return vCardInfo.length > 0 ? vCardInfo.join('\n') : content
    
    case QrCodeType.EMAIL:
      if (content.startsWith('mailto:')) {
        return content.substring(7)
      }
      break
    
    case QrCodeType.PHONE:
      if (content.startsWith('tel:')) {
        return content.substring(4)
      }
      break
    
    case QrCodeType.SMS:
      if (content.startsWith('sms:') || content.startsWith('smsto:')) {
        const prefix = content.startsWith('sms:') ? 'sms:' : 'smsto:'
        return content.substring(prefix.length)
      }
      break
  }
  
  return content
}